1   /*
2    * Copyright (C) 2011 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5    * in compliance with the License. You may obtain a copy of the License at
6    *
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software distributed under the
10   * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11   * express or implied. See the License for the specific language governing permissions and
12   * limitations under the License.
13   */
14  
15  package com.google.common.primitives;
16  
17  import static com.google.common.base.Preconditions.checkArgument;
18  import static com.google.common.base.Preconditions.checkNotNull;
19  
20  import com.google.common.annotations.Beta;
21  import com.google.common.annotations.GwtCompatible;
22  
23  import java.math.BigInteger;
24  import java.util.Arrays;
25  import java.util.Comparator;
26  
27  /**
28   * Static utility methods pertaining to {@code long} primitives that interpret values as
29   * <i>unsigned</i> (that is, any negative value {@code x} is treated as the positive value
30   * {@code 2^64 + x}). The methods for which signedness is not an issue are in {@link Longs}, as
31   * well as signed versions of methods for which signedness is an issue.
32   *
33   * <p>In addition, this class provides several static methods for converting a {@code long} to a
34   * {@code String} and a {@code String} to a {@code long} that treat the {@code long} as an unsigned
35   * number.
36   *
37   * <p>Users of these utilities must be <i>extremely careful</i> not to mix up signed and unsigned
38   * {@code long} values. When possible, it is recommended that the {@link UnsignedLong} wrapper
39   * class be used, at a small efficiency penalty, to enforce the distinction in the type system.
40   *
41   * <p>See the Guava User Guide article on <a href=
42   * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
43   * unsigned primitive utilities</a>.
44   *
45   * @author Louis Wasserman
46   * @author Brian Milch
47   * @author Colin Evans
48   * @since 10.0
49   */
50  @Beta
51  @GwtCompatible
52  public final class UnsignedLongs {
53    private UnsignedLongs() {}
54  
55    public static final long MAX_VALUE = -1L; // Equivalent to 2^64 - 1
56  
57    /**
58     * A (self-inverse) bijection which converts the ordering on unsigned longs to the ordering on
59     * longs, that is, {@code a <= b} as unsigned longs if and only if {@code flip(a) <= flip(b)}
60     * as signed longs.
61     */
62    private static long flip(long a) {
63      return a ^ Long.MIN_VALUE;
64    }
65  
66    /**
67     * Compares the two specified {@code long} values, treating them as unsigned values between
68     * {@code 0} and {@code 2^64 - 1} inclusive.
69     *
70     * @param a the first unsigned {@code long} to compare
71     * @param b the second unsigned {@code long} to compare
72     * @return a negative value if {@code a} is less than {@code b}; a positive value if {@code a} is
73     *         greater than {@code b}; or zero if they are equal
74     */
75    public static int compare(long a, long b) {
76      return Longs.compare(flip(a), flip(b));
77    }
78  
79    /**
80     * Returns the least value present in {@code array}, treating values as unsigned.
81     *
82     * @param array a <i>nonempty</i> array of unsigned {@code long} values
83     * @return the value present in {@code array} that is less than or equal to every other value in
84     *         the array according to {@link #compare}
85     * @throws IllegalArgumentException if {@code array} is empty
86     */
87    public static long min(long... array) {
88      checkArgument(array.length > 0);
89      long min = flip(array[0]);
90      for (int i = 1; i < array.length; i++) {
91        long next = flip(array[i]);
92        if (next < min) {
93          min = next;
94        }
95      }
96      return flip(min);
97    }
98  
99    /**
100    * Returns the greatest value present in {@code array}, treating values as unsigned.
101    *
102    * @param array a <i>nonempty</i> array of unsigned {@code long} values
103    * @return the value present in {@code array} that is greater than or equal to every other value
104    *         in the array according to {@link #compare}
105    * @throws IllegalArgumentException if {@code array} is empty
106    */
107   public static long max(long... array) {
108     checkArgument(array.length > 0);
109     long max = flip(array[0]);
110     for (int i = 1; i < array.length; i++) {
111       long next = flip(array[i]);
112       if (next > max) {
113         max = next;
114       }
115     }
116     return flip(max);
117   }
118 
119   /**
120    * Returns a string containing the supplied unsigned {@code long} values separated by
121    * {@code separator}. For example, {@code join("-", 1, 2, 3)} returns the string {@code "1-2-3"}.
122    *
123    * @param separator the text that should appear between consecutive values in the resulting
124    *        string (but not at the start or end)
125    * @param array an array of unsigned {@code long} values, possibly empty
126    */
127   public static String join(String separator, long... array) {
128     checkNotNull(separator);
129     if (array.length == 0) {
130       return "";
131     }
132 
133     // For pre-sizing a builder, just get the right order of magnitude
134     StringBuilder builder = new StringBuilder(array.length * 5);
135     builder.append(toString(array[0]));
136     for (int i = 1; i < array.length; i++) {
137       builder.append(separator).append(toString(array[i]));
138     }
139     return builder.toString();
140   }
141 
142   /**
143    * Returns a comparator that compares two arrays of unsigned {@code long} values
144    * lexicographically. That is, it compares, using {@link #compare(long, long)}), the first pair of
145    * values that follow any common prefix, or when one array is a prefix of the other, treats the
146    * shorter array as the lesser. For example, {@code [] < [1L] < [1L, 2L] < [2L] < [1L << 63]}.
147    *
148    * <p>The returned comparator is inconsistent with {@link Object#equals(Object)} (since arrays
149    * support only identity equality), but it is consistent with
150    * {@link Arrays#equals(long[], long[])}.
151    *
152    * @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">Lexicographical order
153    *      article at Wikipedia</a>
154    */
155   public static Comparator<long[]> lexicographicalComparator() {
156     return LexicographicalComparator.INSTANCE;
157   }
158 
159   enum LexicographicalComparator implements Comparator<long[]> {
160     INSTANCE;
161 
162     @Override
163     public int compare(long[] left, long[] right) {
164       int minLength = Math.min(left.length, right.length);
165       for (int i = 0; i < minLength; i++) {
166         if (left[i] != right[i]) {
167           return UnsignedLongs.compare(left[i], right[i]);
168         }
169       }
170       return left.length - right.length;
171     }
172   }
173 
174   /**
175    * Returns dividend / divisor, where the dividend and divisor are treated as unsigned 64-bit
176    * quantities.
177    *
178    * @param dividend the dividend (numerator)
179    * @param divisor the divisor (denominator)
180    * @throws ArithmeticException if divisor is 0
181    */
182   public static long divide(long dividend, long divisor) {
183     if (divisor < 0) { // i.e., divisor >= 2^63:
184       if (compare(dividend, divisor) < 0) {
185         return 0; // dividend < divisor
186       } else {
187         return 1; // dividend >= divisor
188       }
189     }
190 
191     // Optimization - use signed division if dividend < 2^63
192     if (dividend >= 0) {
193       return dividend / divisor;
194     }
195 
196     /*
197      * Otherwise, approximate the quotient, check, and correct if necessary. Our approximation is
198      * guaranteed to be either exact or one less than the correct value. This follows from fact
199      * that floor(floor(x)/i) == floor(x/i) for any real x and integer i != 0. The proof is not
200      * quite trivial.
201      */
202     long quotient = ((dividend >>> 1) / divisor) << 1;
203     long rem = dividend - quotient * divisor;
204     return quotient + (compare(rem, divisor) >= 0 ? 1 : 0);
205   }
206 
207   /**
208    * Returns dividend % divisor, where the dividend and divisor are treated as unsigned 64-bit
209    * quantities.
210    *
211    * @param dividend the dividend (numerator)
212    * @param divisor the divisor (denominator)
213    * @throws ArithmeticException if divisor is 0
214    * @since 11.0
215    */
216   public static long remainder(long dividend, long divisor) {
217     if (divisor < 0) { // i.e., divisor >= 2^63:
218       if (compare(dividend, divisor) < 0) {
219         return dividend; // dividend < divisor
220       } else {
221         return dividend - divisor; // dividend >= divisor
222       }
223     }
224 
225     // Optimization - use signed modulus if dividend < 2^63
226     if (dividend >= 0) {
227       return dividend % divisor;
228     }
229 
230     /*
231      * Otherwise, approximate the quotient, check, and correct if necessary. Our approximation is
232      * guaranteed to be either exact or one less than the correct value. This follows from fact
233      * that floor(floor(x)/i) == floor(x/i) for any real x and integer i != 0. The proof is not
234      * quite trivial.
235      */
236     long quotient = ((dividend >>> 1) / divisor) << 1;
237     long rem = dividend - quotient * divisor;
238     return rem - (compare(rem, divisor) >= 0 ? divisor : 0);
239   }
240 
241   /**
242    * Returns the unsigned {@code long} value represented by the given decimal string.
243    *
244    * @throws NumberFormatException if the string does not contain a valid unsigned {@code long}
245    *         value
246    * @throws NullPointerException if {@code s} is null 
247    *         (in contrast to {@link Long#parseLong(String)})
248    */
249   public static long parseUnsignedLong(String s) {
250     return parseUnsignedLong(s, 10);
251   }
252 
253   /**
254    * Returns the unsigned {@code long} value represented by the given string.
255    *
256    * Accepts a decimal, hexadecimal, or octal number given by specifying the following prefix:
257    *
258    * <ul>
259    * <li>{@code 0x}<i>HexDigits</i>
260    * <li>{@code 0X}<i>HexDigits</i>
261    * <li>{@code #}<i>HexDigits</i>
262    * <li>{@code 0}<i>OctalDigits</i>
263    * </ul>
264    *
265    * @throws NumberFormatException if the string does not contain a valid unsigned {@code long}
266    *         value
267    * @since 13.0
268    */
269   public static long decode(String stringValue) {
270     ParseRequest request = ParseRequest.fromString(stringValue);
271 
272     try {
273       return parseUnsignedLong(request.rawValue, request.radix);
274     } catch (NumberFormatException e) {
275       NumberFormatException decodeException =
276           new NumberFormatException("Error parsing value: " + stringValue);
277       decodeException.initCause(e);
278       throw decodeException;
279     }
280   }
281 
282   /**
283    * Returns the unsigned {@code long} value represented by a string with the given radix.
284    *
285    * @param s the string containing the unsigned {@code long} representation to be parsed.
286    * @param radix the radix to use while parsing {@code s}
287    * @throws NumberFormatException if the string does not contain a valid unsigned {@code long}
288    *         with the given radix, or if {@code radix} is not between {@link Character#MIN_RADIX}
289    *         and {@link Character#MAX_RADIX}.
290    * @throws NullPointerException if {@code s} is null 
291    *         (in contrast to {@link Long#parseLong(String)})
292    */
293   public static long parseUnsignedLong(String s, int radix) {
294     checkNotNull(s);
295     if (s.length() == 0) {
296       throw new NumberFormatException("empty string");
297     }
298     if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
299       throw new NumberFormatException("illegal radix: " + radix);
300     }
301 
302     int max_safe_pos = maxSafeDigits[radix] - 1;
303     long value = 0;
304     for (int pos = 0; pos < s.length(); pos++) {
305       int digit = Character.digit(s.charAt(pos), radix);
306       if (digit == -1) {
307         throw new NumberFormatException(s);
308       }
309       if (pos > max_safe_pos && overflowInParse(value, digit, radix)) {
310         throw new NumberFormatException("Too large for unsigned long: " + s);
311       }
312       value = (value * radix) + digit;
313     }
314 
315     return value;
316   }
317 
318   /**
319    * Returns true if (current * radix) + digit is a number too large to be represented by an
320    * unsigned long. This is useful for detecting overflow while parsing a string representation of
321    * a number. Does not verify whether supplied radix is valid, passing an invalid radix will give
322    * undefined results or an ArrayIndexOutOfBoundsException.
323    */
324   private static boolean overflowInParse(long current, int digit, int radix) {
325     if (current >= 0) {
326       if (current < maxValueDivs[radix]) {
327         return false;
328       }
329       if (current > maxValueDivs[radix]) {
330         return true;
331       }
332       // current == maxValueDivs[radix]
333       return (digit > maxValueMods[radix]);
334     }
335 
336     // current < 0: high bit is set
337     return true;
338   }
339 
340   /**
341    * Returns a string representation of x, where x is treated as unsigned.
342    */
343   public static String toString(long x) {
344     return toString(x, 10);
345   }
346 
347   /**
348    * Returns a string representation of {@code x} for the given radix, where {@code x} is treated
349    * as unsigned.
350    *
351    * @param x the value to convert to a string.
352    * @param radix the radix to use while working with {@code x}
353    * @throws IllegalArgumentException if {@code radix} is not between {@link Character#MIN_RADIX}
354    *         and {@link Character#MAX_RADIX}.
355    */
356   public static String toString(long x, int radix) {
357     checkArgument(radix >= Character.MIN_RADIX && radix <= Character.MAX_RADIX,
358         "radix (%s) must be between Character.MIN_RADIX and Character.MAX_RADIX", radix);
359     if (x == 0) {
360       // Simply return "0"
361       return "0";
362     } else {
363       char[] buf = new char[64];
364       int i = buf.length;
365       if (x < 0) {
366         // Separate off the last digit using unsigned division. That will leave
367         // a number that is nonnegative as a signed integer.
368         long quotient = divide(x, radix);
369         long rem = x - quotient * radix;
370         buf[--i] = Character.forDigit((int) rem, radix);
371         x = quotient;
372       }
373       // Simple modulo/division approach
374       while (x > 0) {
375         buf[--i] = Character.forDigit((int) (x % radix), radix);
376         x /= radix;
377       }
378       // Generate string
379       return new String(buf, i, buf.length - i);
380     }
381   }
382 
383   // calculated as 0xffffffffffffffff / radix
384   private static final long[] maxValueDivs = new long[Character.MAX_RADIX + 1];
385   private static final int[] maxValueMods = new int[Character.MAX_RADIX + 1];
386   private static final int[] maxSafeDigits = new int[Character.MAX_RADIX + 1];
387   static {
388     BigInteger overflow = new BigInteger("10000000000000000", 16);
389     for (int i = Character.MIN_RADIX; i <= Character.MAX_RADIX; i++) {
390       maxValueDivs[i] = divide(MAX_VALUE, i);
391       maxValueMods[i] = (int) remainder(MAX_VALUE, i);
392       maxSafeDigits[i] = overflow.toString(i).length() - 1;
393     }
394   }
395 }